%{
	#include <stdio.h>
	#include <stdlib.h>
	#include <string.h>
	#include "../tableSymbole/hashTable.h"
	#include "tableGencode.h"
	#include "tableValueText.h"
	#include "genMips.h"
	#include "variableADeclarer.h"
	#include "pourGestionPile.h"
	#include "pileStructure.h"
	
	extern FILE* yyin;
	FILE* yyout;
	entree temporaire;
	char * bufferItoA;
	int erreurCompilation;
	int boolTemp;
	int nbSysTemp;
	char * charTemp1;
	char * charTemp2;
	int intTemp1;
	int intTemp2;
	int intTemp3;
	int * intEtoileTemp1;
	int * intEtoileTemp2;
%}

%token ENTIER PLUS FOIS PGAUCHE PDROITE IDENTIFIANT POINTVIRGULE AFFECTATION WRITE VAR DEUXPOINTS INT MOINS BOOL STRING NOT OR AND XOR EGAL PPETIT PGRAND PPETITS PGRANDS DIFFERENT BOOLEEN IF THEN ELSE UNIT FUNCTION VIRGULE RETURN PROGRAM TOKENBEGIN TOKENEND READ WHILE DO DIVISER POW
%start debut
%right AFFECTATION
%left PLUS OR MOINS
%left FOIS AND DIVISER
%left XOR 
%right NOT moinsUnaireTop 
%left EGAL PPETIT PGRAND PPETITS PGRANDS DIFFERENT
%nonassoc IDENTIFIANT ENTIER BOOL POW
%nonassoc ifThenTop
%nonassoc ELSE

%%
debut : PROGRAM IDENTIFIANT
		{
			bufferItoA = calloc (32, sizeof(char));
			sprintf(bufferItoA,"%s.s",tableValueText[$2]);				
			
			if ((yyout = fopen(bufferItoA, "w+")) == NULL)
			{
				printf("Erreur : impossible de créer le fichier %s\n", bufferItoA);
				exit(-1);
			}
			
			suppressionTableValueText($2);
		}
		listdecla  listfunct instr
	;
	
listdecla : decla POINTVIRGULE listdecla
	| decla
	|
	;
	
decla : VAR identlist DEUXPOINTS type
		{
			if($4 != ENTREE_TYPECTE_ENTIER && $4 != ENTREE_TYPECTE_BOOL)
			{
				printf("Erreur : Yacc : déclaration  : erreur de type.\n");
				erreurCompilation = 1;
			}
			else
			{
				intTemp3 = $4;
				
				intTemp1 = $2;
				for(intTemp2 = intTemp1; intTemp2 >0; intTemp2 --)
				{
					if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_ID)
					{
						printf("Erreur : VAR identlist DEUXPOINTS type : la tête de pile n'est pas un identifiant.\n");
						erreurCompilation = 1;
					}
					else if(((structureID)pileStructure[nbPileStructure-1]->valeur)->type != ENTREE_TYPECTE_BOOL)
					{
						printf("Erreur : Yacc :VAR identlist DEUXPOINTS type : la tête de pile n'est pas celle attendue.\n");
						erreurCompilation = 1;
					}
					else
					{			
						if(intTemp3 == ENTREE_TYPECTE_ENTIER)
						{
							ajoutEntreeHashTable(nouvelleEntreeCteInt(((structureID)pileStructure[nbPileStructure-1]->valeur)->nom, 0));
						}
						else
						{		
							ajoutEntreeHashTable(nouvelleEntreeCteBool(((structureID)pileStructure[nbPileStructure-1]->valeur)->nom, FAUX));
						}
				
					}
					
					suppressionTetePileStructure();
				}
			}
		}
	;
	
identlist : IDENTIFIANT
		{
			ajoutPileStructureID(tableValueText[$1], ENTREE_TYPECTE_BOOL);		
			$$ = 1;
			suppressionTableValueText($1);
		}
	| IDENTIFIANT VIRGULE identlist
		{
			ajoutPileStructureID(tableValueText[$1], ENTREE_TYPECTE_BOOL);
			$$ = $3 + 1;
			suppressionTableValueText($1);
		}
	;
	
type : INT
		{
			$$ = ENTREE_TYPECTE_ENTIER;
		}
	| BOOLEEN
		{
			$$ = ENTREE_TYPECTE_BOOL;
		}
	;

listfunct : functdecla POINTVIRGULE listfunct
	|
	;
	
functdecla : FUNCTION IDENTIFIANT 
		{
			entreeBloc();
		
			intTemp1 = ajoutTableGencode("fonction",tableValueText[$2],"","");
			printf("\tajout (%d) : %s %s, %s, %s\n",intTemp1, tableGencode[intTemp1]->commande,tableGencode[intTemp1]->adresse1,tableGencode[intTemp1]->adresse2,tableGencode[intTemp1]->adresse3);
		
			ajoutPileStructureFONCTION(tableValueText[$2],0,NULL,0);
			suppressionTableValueText($2);			
		}
		PGAUCHE arglist PDROITE DEUXPOINTS typeretour 
		{
			if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_FONCTION)
			{
				printf("Erreur : Yacc : PGAUCHE arglist PDROITE DEUXPOINTS typeretour : la tete de pile n'est pas une focntion.\n");
				erreurCompilation = 1;
			}
			else
			{
				((structureFONCTION)(pileStructure[nbPileStructure-1]->valeur))->typeRetour = $8;
			}
		}
		listdecla instr
		{
			//TODO tester le return
			/*
			if(((structureFONCTION)(pileStructure[nbPileStructure-1]->valeur))->typeRetour == ENTREE_TYPECTE_UNIT)
			{//on ne doit pas avoir de return en dernière instruction
				
			}
			else
			{//on doit avoir un return en dernière instruction
			
			}
			*/
			
			if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_FONCTION)
			{
				printf("Erreur : Yacc : PGAUCHE arglist PDROITE DEUXPOINTS typeretour : la tete de pile n'est pas une focntion.\n");
				erreurCompilation = 1;
			}
			else
			{
				intTemp1 = ((structureFONCTION)(pileStructure[nbPileStructure-1]->valeur))->nbArg;
				intTemp2 = ((structureFONCTION)(pileStructure[nbPileStructure-1]->valeur))->typeRetour;
				charTemp1 = ((structureFONCTION)(pileStructure[nbPileStructure-1]->valeur))->nom;
				intEtoileTemp1 = ((structureFONCTION)(pileStructure[nbPileStructure-1]->valeur))->typeArg;
				
				suppressionTetePileStructure();
				
				sortieBloc();
				
				ajoutEntreeHashTable(nouvelleEntreeFct(charTemp1, intTemp1, intEtoileTemp1, intTemp2));
				
				intTemp1 = ajoutTableGencode("finFonction","","","");
				printf("\tajout (%d) : %s %s, %s, %s\n",intTemp1, tableGencode[intTemp1]->commande,tableGencode[intTemp1]->adresse1,tableGencode[intTemp1]->adresse2,tableGencode[intTemp1]->adresse3);
			}
		}
	;
	
arglist : arg VIRGULE arglist
	| arg
	|
	;

arg : IDENTIFIANT DEUXPOINTS type
		{
			if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_FONCTION)
			{
				printf("Erreur : Yacc : arg : IDENTIFIANT DEUXPOINTS type : la tete de pile n'est pas une focntion.\n");
				erreurCompilation = 1;
			}
			else
			{
				intTemp1 = ((structureFONCTION)(pileStructure[nbPileStructure-1]->valeur))->nbArg;
				
				if(intTemp1 > 3)
				{
					printf("Erreur : Yacc : arg : IDENTIFIANT DEUXPOINTS type : la fonction a déjà 4 arguments (maximum autorisé).\n"); //a0 à a3 ...
					erreurCompilation = 1;
				}
				else
				{				
					intTemp1++;
					intEtoileTemp2 = malloc(sizeof(int)*intTemp1);
					
					if(intTemp1 > 1)
					{//la liste n'était  pas vide
						intEtoileTemp1 = ((structureFONCTION)(pileStructure[nbPileStructure-1]->valeur))->typeArg;
						for(intTemp2=0;intTemp2<intTemp1-1;intTemp2++)
						{
							intEtoileTemp2[intTemp2] = intEtoileTemp1[intTemp2];
						}
						
						intEtoileTemp2[intTemp2] = $3;
					}
					else
					{
						intEtoileTemp2[0] = $3;
					}
					
					((structureFONCTION)(pileStructure[nbPileStructure-1]->valeur))->typeArg = intEtoileTemp2;
					((structureFONCTION)(pileStructure[nbPileStructure-1]->valeur))->nbArg = intTemp1;
					
					if($3 == ENTREE_TYPECTE_ENTIER)
					{
						ajoutEntreeHashTable(nouvelleEntreeCteInt(tableValueText[$1], 0));
					}
					else if($3 = ENTREE_TYPECTE_BOOL)
					{
						ajoutEntreeHashTable(nouvelleEntreeCteBool(tableValueText[$1], FAUX));
					}
					else
					{
						printf("Erreur : arg : IDENTIFIANT DEUXPOINTS type : erreur de type.\n",tableValueText[$1]);
						erreurCompilation = 1;
					}
					
					bufferItoA = calloc (16, sizeof(char));
					sprintf(bufferItoA,"$a%d",intTemp1-1);					
					intTemp1 = ajoutTableGencode("chargerDeParametre",tableValueText[$1],bufferItoA,"");
					printf("\tajout (%d) : %s %s, %s, %s\n",intTemp1, tableGencode[intTemp1]->commande,tableGencode[intTemp1]->adresse1,tableGencode[intTemp1]->adresse2,tableGencode[intTemp1]->adresse3);
			
					suppressionTableValueText($1);
				}
			}
		}
	;

typeretour : INT
		{
			$$ = ENTREE_TYPECTE_ENTIER;
		}
	| BOOLEEN
		{
			$$ = ENTREE_TYPECTE_BOOL;
		}
	| UNIT
		{
			$$ = ENTREE_TYPECTE_UNIT;
		}
	;
	
listinstr : instr POINTVIRGULE listinstr
	| instr POINTVIRGULE
	| instr
	;
	
instr : IDENTIFIANT AFFECTATION	E
		{			
			if(!existeMotClefHashTableHorsVide(tableValueText[$1]))
			{
				printf("Erreur : Yacc : IDENTIFIANT AFFECTATION	E : identifiant non declare (%s).\n",tableValueText[$1]);
				erreurCompilation = 1;
			}
			else
			{				
				if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_ID)
				{
					printf("Erreur : Yacc : IDENTIFIANT AFFECTATION	E : E n'est pas un identifiant.\n");
					erreurCompilation = 1;
				}
				else if(((structureID)pileStructure[nbPileStructure-1]->valeur)->type != consulteHashTable(tableValueText[$1]).valeur.type)
				{
					printf("Erreur : Yacc : IDENTIFIANT AFFECTATION	E : l'identifiant et E ne sont pas du même type.\n");
					erreurCompilation = 1;
				}
				else
				{
					charTemp1 = ((structureID)(pileStructure[nbPileStructure-1]->valeur))->nom;
					suppressionTetePileStructure();
					printf("\trécupération de %s dans la pileStructure\n",charTemp1);
					
					intTemp1 = ajoutTableGencode("affectation",tableValueText[$1],charTemp1,"");
					printf("\tajout (%d) : %s %s, %s, %s\n",intTemp1, tableGencode[intTemp1]->commande,tableGencode[intTemp1]->adresse1,tableGencode[intTemp1]->adresse2,tableGencode[intTemp1]->adresse3);
				}
			}
			suppressionTableValueText($1);
		}
	| WRITE E
		{
			if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : WRITE E : E n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-1]->valeur)->type == ENTREE_TYPECTE_BOOL)
			{
				intTemp1 = ajoutTableGencode("ecritureBool",((structureID)pileStructure[nbPileStructure-1]->valeur)->nom,"","");
				printf("\tajout (%d) : %s %s, %s, %s\n",intTemp1, tableGencode[intTemp1]->commande,tableGencode[intTemp1]->adresse1,tableGencode[intTemp1]->adresse2,tableGencode[intTemp1]->adresse3);
			}
			else if(((structureID)pileStructure[nbPileStructure-1]->valeur)->type == ENTREE_TYPECTE_ENTIER)
			{
				intTemp1 = ajoutTableGencode("ecriture",((structureID)pileStructure[nbPileStructure-1]->valeur)->nom,"","");
				printf("\tajout (%d) : %s %s, %s, %s\n",intTemp1, tableGencode[intTemp1]->commande,tableGencode[intTemp1]->adresse1,tableGencode[intTemp1]->adresse2,tableGencode[intTemp1]->adresse3);
			}
			else
			{
				printf("Erreur : Yacc : WRITE E : E n'est ni un entier, ni un booleen.\n");
				erreurCompilation = 1;
			}
			
			suppressionTetePileStructure();
		}
	| WRITE STRING
		{
			if(strcmp(tableValueText[$2],"\"\\n\"") == 0)
			{
				intTemp1 = ajoutTableGencode("ecritureString","sys_retour_ligne","","");
				printf("\tajout (%d) : %s %s, %s, %s\n",intTemp1,tableGencode[intTemp1]->commande,tableGencode[intTemp1]->adresse1,tableGencode[intTemp1]->adresse2,tableGencode[intTemp1]->adresse3);
			}
			else if(strcmp(tableValueText[$2],"\"\\t\"") == 0)
			{
				intTemp1 = ajoutTableGencode("ecritureString","sys_tabulation","","");
				printf("\tajout (%d) : %s %s, %s, %s\n",intTemp1,tableGencode[intTemp1]->commande,tableGencode[intTemp1]->adresse1,tableGencode[intTemp1]->adresse2,tableGencode[intTemp1]->adresse3);
			}
			else if(strcmp(tableValueText[$2],"\" \"") == 0)
			{
				intTemp1 = ajoutTableGencode("ecritureString","sys_espace","","");
				printf("\tajout (%d) : %s %s, %s, %s\n",intTemp1,tableGencode[intTemp1]->commande,tableGencode[intTemp1]->adresse1,tableGencode[intTemp1]->adresse2,tableGencode[intTemp1]->adresse3);
			}
			else
			{
				//générer une varaible temporaire pour E
				bufferItoA = calloc (16, sizeof(char));
				sprintf(bufferItoA,"_SysTemp%d",nbSysTemp);
				ajoutEntreeHashTable(nouvelleEntreeCteChar(bufferItoA, tableValueText[$2]));
				nbSysTemp++;
				printf("\t%s var temp\n",bufferItoA);
				
				intTemp1 = ajoutTableGencode("ecritureString",bufferItoA,"","");
				printf("\tajout (%d) : %s %s, %s, %s\n",intTemp1,tableGencode[intTemp1]->commande,tableGencode[intTemp1]->adresse1,tableGencode[intTemp1]->adresse2,tableGencode[intTemp1]->adresse3);
			}

			suppressionTableValueText($2);
		}
	| ifthen %prec  ifThenTop
		{
			if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_IFTHENELSE)
			{
				printf("Erreur : Yacc : IF E THEN instr ELSE instr : la tete de la pile structure n'est pas une reservation de labels.\n");
				erreurCompilation = 1;
			}
			else
			{				
				intTemp1 = ((structureIFTHENELSE)pileStructure[nbPileStructure-1]->valeur)->xfaux;
				intTemp2 = ((structureIFTHENELSE)pileStructure[nbPileStructure-1]->valeur)->xfin;			
				
				bufferItoA = calloc (16, sizeof(char));
				sprintf(bufferItoA,"_SysLabelGenMips%d",intTemp1);
				ajoutTableGencode("label",bufferItoA,"","");
			}
		}
	| ifthen ELSE
		{
			if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_IFTHENELSE)
			{
				printf("Erreur : Yacc : IF E THEN instr ELSE instr : la tete de la pile structure n'est pas une reservation de labels.\n");
				erreurCompilation = 1;
			}
			else
			{				
				intTemp1 = ((structureIFTHENELSE)pileStructure[nbPileStructure-1]->valeur)->xfaux;
				intTemp2 = ((structureIFTHENELSE)pileStructure[nbPileStructure-1]->valeur)->xfin;			
				
				bufferItoA = calloc (16, sizeof(char));
				sprintf(bufferItoA,"_SysLabelGenMips%d",intTemp2);
				ajoutTableGencode("jump",bufferItoA,"","");
				
				bufferItoA = calloc (16, sizeof(char));
				sprintf(bufferItoA,"_SysLabelGenMips%d",intTemp1);
				ajoutTableGencode("label",bufferItoA,"","");
			}
		}
		instr
		{
			if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_IFTHENELSE)
			{
				printf("Erreur : Yacc : IF E THEN instr ELSE instr : la tete de la pile structure n'est pas une reservation de labels.\n");
				erreurCompilation = 1;
			}
			else
			{				
				intTemp2 = ((structureIFTHENELSE)pileStructure[nbPileStructure-1]->valeur)->xfin;			
				
				bufferItoA = calloc (16, sizeof(char));
				sprintf(bufferItoA,"_SysLabelGenMips%d",intTemp2);
				ajoutTableGencode("label",bufferItoA,"","");
			}
		}
	| appelfonction
		{
			if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_FONCTION)
			{
				printf("Erreur : Yacc : instr -> appelfonction : la tete de pile n'est pas une focntion.\n");
				erreurCompilation = 1;
			}
			else
			{
				suppressionTetePileStructure();
			}
		}
	| RETURN E
		{
			if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : instr -> return E : E n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-1]->valeur)->type == ENTREE_TYPECTE_BOOL || ((structureID)pileStructure[nbPileStructure-1]->valeur)->type == ENTREE_TYPECTE_ENTIER)
			{			
				charTemp1 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->nom;
				suppressionTetePileStructure();
				printf("\trécupération de %s dans la pileStructure\n",charTemp1);
				
				if(!existeMotClefHashTableHorsVide(charTemp1))
				{
					printf("Erreur : Yacc : instr -> return E : E non declare (%s).\n",charTemp1);
					erreurCompilation = 1;
				}			
				else
				{
					intTemp1 = ajoutTableGencode("return",charTemp1,"","");
					printf("\tajout (%d) : %s %s, %s, %s\n",intTemp1, tableGencode[intTemp1]->commande,tableGencode[intTemp1]->adresse1,tableGencode[intTemp1]->adresse2,tableGencode[intTemp1]->adresse3);
				}
			}
			else
			{			
				printf("Erreur : Yacc : E -> not E1 : E1 n'est pas un booleen.\n");
				erreurCompilation = 1;
			}
		}
	| RETURN
		{
			//TODO test return
		}
	| TOKENBEGIN listinstr TOKENEND
	| TOKENBEGIN TOKENEND
	| READ IDENTIFIANT
		{
			if(!existeMotClefHashTableHorsVide(tableValueText[$2]))
			{
				printf("Erreur : Yacc : READ IDENTIFIANT : identifiant non declare (%s).\n",tableValueText[$2]);
				erreurCompilation = 1;
			}
			else if(consulteHashTable(tableValueText[$2]).valeur.type == ENTREE_TYPECTE_ENTIER)
			{
				intTemp1 = ajoutTableGencode("readEntier",tableValueText[$2],"","");
				printf("\tajout (%d) : %s %s, %s, %s\n",intTemp1, tableGencode[intTemp1]->commande,tableGencode[intTemp1]->adresse1,tableGencode[intTemp1]->adresse2,tableGencode[intTemp1]->adresse3);
			}
			else if(consulteHashTable(tableValueText[$2]).valeur.type == ENTREE_TYPECTE_BOOL)
			{
				intTemp1 = ajoutTableGencode("readBooleen",tableValueText[$2],"","");
				printf("\tajout (%d) : %s %s, %s, %s\n",intTemp1, tableGencode[intTemp1]->commande,tableGencode[intTemp1]->adresse1,tableGencode[intTemp1]->adresse2,tableGencode[intTemp1]->adresse3);
			}
			else
			{
				printf("Erreur : Yacc : READ IDENTIFIANT : identifiant n'est ni un entier ni un booleen (%s).\n",tableValueText[$2]);
				erreurCompilation = 1;
			}			
			
			suppressionTableValueText($2);
		}
	| WHILE
		{
			intTemp1 = nbLabelPourGenMips;
			nbLabelPourGenMips += 2;
			
			bufferItoA = calloc (16, sizeof(char));
			sprintf(bufferItoA,"_SysLabelGenMips%d",intTemp1);
			ajoutTableGencode("label",bufferItoA,"","");
			
			ajoutPileStructureWHILE(intTemp1,intTemp1+1);
		}
		E 
		{
			if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : WHILE E DO instr : E n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-1]->valeur)->type == ENTREE_TYPECTE_BOOL)
			{				
				charTemp1 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->nom;
				suppressionTetePileStructure();
				
				if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_WHILE)
				{
					printf("Erreur : Yacc : WHILE E DO instr : la tete de la pile structure n'est pas une reservation de labels.\n");
					erreurCompilation = 1;
				}
				else
				{				
					intTemp1 = ((structureWHILE)pileStructure[nbPileStructure-1]->valeur)->xdebut;
					intTemp2 = ((structureWHILE)pileStructure[nbPileStructure-1]->valeur)->xfin;			
					
					bufferItoA = calloc (16, sizeof(char));
					sprintf(bufferItoA,"_SysLabelGenMips%d",intTemp2);
					ajoutTableGencode("if",charTemp1,bufferItoA,"");
				}
			}
			else
			{
				printf("Erreur : Yacc : WHILE E DO instr : E n'est pas un booleen.\n");
				erreurCompilation = 1;
			}
		}
		DO instr
		{
			if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_WHILE)
			{
				printf("Erreur : Yacc : WHILE E DO instr : la tete de la pile structure n'est pas une reservation de labels.\n");
				erreurCompilation = 1;
			}
			else
			{				
				intTemp1 = ((structureWHILE)pileStructure[nbPileStructure-1]->valeur)->xdebut;
				intTemp2 = ((structureWHILE)pileStructure[nbPileStructure-1]->valeur)->xfin;			
				
				bufferItoA = calloc (16, sizeof(char));
				sprintf(bufferItoA,"_SysLabelGenMips%d",intTemp1);
				ajoutTableGencode("jump",bufferItoA,"","");
				
				bufferItoA = calloc (16, sizeof(char));
				sprintf(bufferItoA,"_SysLabelGenMips%d",intTemp2);
				ajoutTableGencode("label",bufferItoA,"","");
			}
			
			suppressionTetePileStructure();
		}
	;
	
E 	: E op2		
		{			
			if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : E -> E1 op2 : E1 n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else
			{			
				charTemp1 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->nom;
				suppressionTetePileStructure();
				printf("\trécupération de %s dans la pileStructure\n",charTemp1);
				
				if(!existeMotClefHashTableHorsVide(charTemp1))
				{
					printf("Erreur : Yacc : E -> E1 op2 : E1 : identifiant non declare (%s).\n",charTemp1);
					erreurCompilation = 1;
				}
				else
				{
					tableGencode[$2]->adresse2 = charTemp1;
					printf("\tajout infos à %d : %s %s, %s, %s\n",$2, tableGencode[$2]->commande,tableGencode[$2]->adresse1,tableGencode[$2]->adresse2,tableGencode[$2]->adresse3);					
				}
			}
		}
	| MOINS E %prec moinsUnaireTop 		
		{				
			if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : E -> - E1 : E1 n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-1]->valeur)->type != ENTREE_TYPECTE_ENTIER)
			{
				printf("Erreur : Yacc : E -> - E1 : E1 n'est pas un entier.\n");
				erreurCompilation = 1;
			}
			else
			{									
				//générer une varaible temporaire pour E
				bufferItoA = calloc (16, sizeof(char));
				sprintf(bufferItoA,"_SysTemp%d",nbSysTemp);
				ajoutEntreeHashTable(nouvelleEntreeCteInt(bufferItoA, 0));
				nbSysTemp++;
				printf("\t%s var temp\n",bufferItoA); 
			
				charTemp1 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->nom;
				suppressionTetePileStructure();
				printf("\trécupération de %s dans la pileStructure\n",charTemp1);
				
				if(!existeMotClefHashTableHorsVide(charTemp1))
				{
					printf("Erreur : Yacc : E -> - E1 : E1 : identifiant non declare (%s).\n",charTemp1);
					erreurCompilation = 1;
				}			
				else
				{
					intTemp1 = ajoutTableGencode("moinsUnaire",bufferItoA,charTemp1,"");
					printf("\tajout (%d) : %s %s, %s, %s\n",intTemp1, tableGencode[intTemp1]->commande,tableGencode[intTemp1]->adresse1,tableGencode[intTemp1]->adresse2,tableGencode[intTemp1]->adresse3);
					
					ajoutPileStructureID(bufferItoA, ENTREE_TYPECTE_ENTIER);
					printf("\tajout pile %s\n",bufferItoA);
				}
			}
		}
	| PGAUCHE E PDROITE 		
		{
			//on fait rien -> recopie
		}
	| IDENTIFIANT
		{
			if(!existeMotClefHashTableHorsVide(tableValueText[$1]))
			{
				printf("Erreur : Yacc : E -> IDENTIFIANT : identifiant non declare (%s).\n",tableValueText[$1]);
				erreurCompilation = 1;
			}
			else if(consulteHashTable(tableValueText[$1]).valeur.type == ENTREE_TYPECTE_ENTIER)
			{
				ajoutPileStructureID(tableValueText[$1], ENTREE_TYPECTE_ENTIER);
				printf("\tajout pile %s\n",tableValueText[$1]);
			}
			else if(consulteHashTable(tableValueText[$1]).valeur.type == ENTREE_TYPECTE_BOOL)
			{
				ajoutPileStructureID(tableValueText[$1], ENTREE_TYPECTE_BOOL);
				printf("\tajout pile %s\n",tableValueText[$1]);		
			}
			else
			{
				printf("Erreur : Yacc : E -> IDENTIFIANT : identifiant n'est ni un entier ni un booleen (%s).\n",tableValueText[$1]);
				erreurCompilation = 1;
			}			
			
			suppressionTableValueText($1);
		}
	| ENTIER 		
		{
			//générer une varaible temporaire pour E
			bufferItoA = calloc (16, sizeof(char));
			sprintf(bufferItoA,"_SysTemp%d",nbSysTemp);
			ajoutEntreeHashTable(nouvelleEntreeCteInt(bufferItoA, 0));
			nbSysTemp++;
			printf("\t%s var temp\n",bufferItoA);
			
			charTemp1 = calloc (16, sizeof(char));
			sprintf(charTemp1,"%d",$1);
			intTemp1 = ajoutTableGencode("affectationVal",bufferItoA,charTemp1,"");
			printf("\tajout (%d) : %s %s, %s, %s\n",intTemp1,tableGencode[intTemp1]->commande,tableGencode[intTemp1]->adresse1,tableGencode[intTemp1]->adresse2,tableGencode[intTemp1]->adresse3);
			
			ajoutPileStructureID(bufferItoA, ENTREE_TYPECTE_ENTIER);
			printf("\tajout pile %s\n",bufferItoA);
		} 
	| NOT E		
		{
			if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : E -> not E1 : E1 n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-1]->valeur)->type != ENTREE_TYPECTE_BOOL)
			{
				printf("Erreur : Yacc : E -> not E1 : E1 n'est pas un booleen.\n");
				erreurCompilation = 1;
			}
			else
			{				
				//générer une varaible temporaire pour B
				bufferItoA = calloc (16, sizeof(char));
				sprintf(bufferItoA,"_SysTemp%d",nbSysTemp);
				ajoutEntreeHashTable(nouvelleEntreeCteBool(bufferItoA, FAUX));
				nbSysTemp++;
				printf("\t%s var temp\n",bufferItoA);
			
				charTemp1 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->nom;
				suppressionTetePileStructure();
				printf("\trécupération de %s dans la pileStructure\n",charTemp1);
				
				if(!existeMotClefHashTableHorsVide(charTemp1))
				{
					printf("Erreur : Yacc : E -> not E1 : E1 : identifiant non declare (%s).\n",charTemp1);
					erreurCompilation = 1;
				}			
				else
				{
					intTemp1 = ajoutTableGencode("logiqueNot",bufferItoA,charTemp1,"");
					printf("\tajout (%d) : %s %s, %s, %s\n",intTemp1, tableGencode[intTemp1]->commande,tableGencode[intTemp1]->adresse1,tableGencode[intTemp1]->adresse2,tableGencode[intTemp1]->adresse3);
					
					ajoutPileStructureID(bufferItoA, ENTREE_TYPECTE_BOOL);
					printf("\tajout pile %s\n",bufferItoA);
				}
			}
		}
	| BOOL		
		{
			//générer une varaible temporaire pour E
			bufferItoA = calloc (16, sizeof(char));
			sprintf(bufferItoA,"_SysTemp%d",nbSysTemp);
			ajoutEntreeHashTable(nouvelleEntreeCteBool(bufferItoA, FAUX));
			nbSysTemp++;
			printf("\t%s var temp\n",bufferItoA);
			
			charTemp1 = calloc (16, sizeof(char));
			sprintf(charTemp1,"%d",$1);
			intTemp1 = ajoutTableGencode("affectationVal",bufferItoA,charTemp1,"");
			printf("\tajout (%d) : %s %s, %s, %s\n",intTemp1,tableGencode[intTemp1]->commande,tableGencode[intTemp1]->adresse1,tableGencode[intTemp1]->adresse2,tableGencode[intTemp1]->adresse3);
			
			ajoutPileStructureID(bufferItoA, ENTREE_TYPECTE_BOOL);
			printf("\tajout pile %s\n",bufferItoA);
		}
	| appelfonction
		{
			if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_FONCTION)
			{
				printf("Erreur : Yacc : E -> appelfonction : la tete de pile n'est pas une focntion.\n");
				erreurCompilation = 1;
			}
			else if(((structureFONCTION)(pileStructure[nbPileStructure-1]->valeur))->typeRetour == ENTREE_TYPECTE_BOOL)
			{
				//générer une varaible temporaire pour E
				bufferItoA = calloc (16, sizeof(char));
				sprintf(bufferItoA,"_SysTemp%d",nbSysTemp);
				ajoutEntreeHashTable(nouvelleEntreeCteBool(bufferItoA, FAUX));
				nbSysTemp++;
				printf("\t%s var temp\n",bufferItoA);
			
				suppressionTetePileStructure();
				
				intTemp1 = ajoutTableGencode("chargerResultatDans",bufferItoA,"","");
				printf("\tajout (%d) : %s %s, %s, %s\n",intTemp1,tableGencode[intTemp1]->commande,tableGencode[intTemp1]->adresse1,tableGencode[intTemp1]->adresse2,tableGencode[intTemp1]->adresse3);
				
				ajoutPileStructureID(bufferItoA, ENTREE_TYPECTE_BOOL);
				printf("\tajout pile %s\n",bufferItoA);
			}
			else if(((structureFONCTION)(pileStructure[nbPileStructure-1]->valeur))->typeRetour == ENTREE_TYPECTE_ENTIER)
			{
				//générer une varaible temporaire pour E
				bufferItoA = calloc (16, sizeof(char));
				sprintf(bufferItoA,"_SysTemp%d",nbSysTemp);
				ajoutEntreeHashTable(nouvelleEntreeCteInt(bufferItoA, 0));
				nbSysTemp++;
				printf("\t%s var temp\n",bufferItoA);
			
				suppressionTetePileStructure();
				
				intTemp1 = ajoutTableGencode("chargerResultatDans",bufferItoA,"","");
				printf("\tajout (%d) : %s %s, %s, %s\n",intTemp1,tableGencode[intTemp1]->commande,tableGencode[intTemp1]->adresse1,tableGencode[intTemp1]->adresse2,tableGencode[intTemp1]->adresse3);
				
				ajoutPileStructureID(bufferItoA, ENTREE_TYPECTE_ENTIER);
				printf("\tajout pile %s\n",bufferItoA);
			}
			else
			{
				printf("Erreur : Yacc : E -> appelfonction : le retour de fonction n'est ni entier ni booleen.\n");
				erreurCompilation = 1;
			}
		}
	;	
	
op2 : FOIS E		
		{	
			if(pileStructure[nbPileStructure-2] == NULL || pileStructure[nbPileStructure-2]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : E -> E1 * E2 : E1 n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-2]->valeur)->type != ENTREE_TYPECTE_ENTIER)
			{
				printf("Erreur : Yacc : E -> E1 * E2 : E1 n'est pas un entier.\n");
				erreurCompilation = 1;
			} 
			else if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : E -> E1 * E2 : E2 n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-1]->valeur)->type != ENTREE_TYPECTE_ENTIER)
			{
				printf("Erreur : Yacc : E -> E1 * E2 : E2 n'est pas un entier.\n");
				erreurCompilation = 1;
			}
			else
			{				
				//générer une varaible temporaire pour E
				bufferItoA = calloc (16, sizeof(char));
				sprintf(bufferItoA,"_SysTemp%d",nbSysTemp);
				ajoutEntreeHashTable(nouvelleEntreeCteInt(bufferItoA, 0));
				nbSysTemp++;
				printf("\t%s var temp\n",bufferItoA);
				
				charTemp1 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->nom;
				suppressionTetePileStructure();
				printf("\trécupération de %s dans la pileStructure\n",charTemp1);
				
				if(!existeMotClefHashTableHorsVide(charTemp1))
				{
					printf("Erreur : Yacc : E -> E1 * E2 : E2 : identifiant non declare (%s).\n",charTemp1);
					erreurCompilation = 1;
				}
				else
				{
					$$ = ajoutTableGencode("multiplication",bufferItoA,"",charTemp1);
					printf("\tajout (%d) : %s %s, %s, %s\n",$$,tableGencode[$$]->commande,tableGencode[$$]->adresse1,tableGencode[$$]->adresse2,tableGencode[$$]->adresse3);
					
					//on veut ajouter à la pile E (E -> E1 op2 E2). Mais E1 est au sommet de la pile et on en a besoin lors de la réduction.
					//on supprime donc E1 de la pile, on ajoute E, on ajoute à nouveau E1. Ainsi on conserve l'ordre
					intTemp2 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->type;
					charTemp2 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->nom;
					suppressionTetePileStructure();
					ajoutPileStructureID(bufferItoA, ENTREE_TYPECTE_ENTIER);
					printf("\tajout pile %s\n",bufferItoA);	
					ajoutPileStructureID(charTemp2, intTemp2);
					printf("\tajout pile %s\n",charTemp2);	
				}
			}
		}
	| DIVISER E		
		{	
			if(pileStructure[nbPileStructure-2] == NULL || pileStructure[nbPileStructure-2]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : E -> E1 / E2 : E1 n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-2]->valeur)->type != ENTREE_TYPECTE_ENTIER)
			{
				printf("Erreur : Yacc : E -> E1 / E2 : E1 n'est pas un entier.\n");
				erreurCompilation = 1;
			} 
			else if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : E -> E1 / E2 : E2 n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-1]->valeur)->type != ENTREE_TYPECTE_ENTIER)
			{
				printf("Erreur : Yacc : E -> E1 / E2 : E2 n'est pas un entier.\n");
				erreurCompilation = 1;
			}
			else
			{				
				//générer une varaible temporaire pour E
				bufferItoA = calloc (16, sizeof(char));
				sprintf(bufferItoA,"_SysTemp%d",nbSysTemp);
				ajoutEntreeHashTable(nouvelleEntreeCteInt(bufferItoA, 0));
				nbSysTemp++;
				printf("\t%s var temp\n",bufferItoA);
				
				charTemp1 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->nom;
				suppressionTetePileStructure();
				printf("\trécupération de %s dans la pileStructure\n",charTemp1);
				
				if(!existeMotClefHashTableHorsVide(charTemp1))
				{
					printf("Erreur : Yacc : E -> E1 / E2 : E2 : identifiant non declare (%s).\n",charTemp1);
					erreurCompilation = 1;
				}
				else
				{
					$$ = ajoutTableGencode("division",bufferItoA,"",charTemp1);
					printf("\tajout (%d) : %s %s, %s, %s\n",$$,tableGencode[$$]->commande,tableGencode[$$]->adresse1,tableGencode[$$]->adresse2,tableGencode[$$]->adresse3);
					
					//on veut ajouter à la pile E (E -> E1 op2 E2). Mais E1 est au sommet de la pile et on en a besoin lors de la réduction.
					//on supprime donc E1 de la pile, on ajoute E, on ajoute à nouveau E1. Ainsi on conserve l'ordre
					intTemp2 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->type;
					charTemp2 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->nom;
					suppressionTetePileStructure();
					ajoutPileStructureID(bufferItoA, ENTREE_TYPECTE_ENTIER);
					printf("\tajout pile %s\n",bufferItoA);	
					ajoutPileStructureID(charTemp2, intTemp2);
					printf("\tajout pile %s\n",charTemp2);	
				}
			}
		}
	| PLUS E		
		{
			if(pileStructure[nbPileStructure-2] == NULL || pileStructure[nbPileStructure-2]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : E -> E1 + E2 : E1 n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-2]->valeur)->type != ENTREE_TYPECTE_ENTIER)
			{
				printf("Erreur : Yacc : E -> E1 + E2 : E1 n'est pas un entier.\n");
				erreurCompilation = 1;
			} 
			else if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : E -> E1 + E2 : E2 n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-1]->valeur)->type != ENTREE_TYPECTE_ENTIER)
			{
				printf("Erreur : Yacc : E -> E1 + E2 : E2 n'est pas un entier.\n");
				erreurCompilation = 1;
			}
			else
			{				
				//générer une varaible temporaire pour E
				bufferItoA = calloc (16, sizeof(char));
				sprintf(bufferItoA,"_SysTemp%d",nbSysTemp);
				ajoutEntreeHashTable(nouvelleEntreeCteInt(bufferItoA, 0));
				nbSysTemp++;
				printf("\t%s var temp\n",bufferItoA);
				
				charTemp1 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->nom;
				suppressionTetePileStructure();
				printf("\trécupération de %s dans la pileStructure\n",charTemp1);
				
				if(!existeMotClefHashTableHorsVide(charTemp1))
				{
					printf("Erreur : Yacc : E -> E1 + E2 : E2 : identifiant non declare (%s).\n",charTemp1);
					erreurCompilation = 1;
				}
				else
				{
					$$ = ajoutTableGencode("addition",bufferItoA,"",charTemp1);
					printf("\tajout : %s %s, %s, %s\n",tableGencode[$$]->commande,tableGencode[$$]->adresse1,tableGencode[$$]->adresse2,tableGencode[$$]->adresse3);
					
					//on veut ajouter à la pile E (E -> E1 op2 E2). Mais E1 est au sommet de la pile et on en a besoin lors de la réduction.
					//on supprime donc E1 de la pile, on ajoute E, on ajoute à nouveau E1. Ainsi on conserve l'ordre
					intTemp2 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->type;
					charTemp2 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->nom;
					suppressionTetePileStructure();
					ajoutPileStructureID(bufferItoA, ENTREE_TYPECTE_ENTIER);
					printf("\tajout pile %s\n",bufferItoA);	
					ajoutPileStructureID(charTemp2, intTemp2);
					printf("\tajout pile %s\n",charTemp2);	
				}
			}
		}
	| MOINS E		
		{
			if(pileStructure[nbPileStructure-2] == NULL || pileStructure[nbPileStructure-2]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : E -> E1 - E2 : E1 n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-2]->valeur)->type != ENTREE_TYPECTE_ENTIER)
			{
				printf("Erreur : Yacc : E -> E1 - E2 : E1 n'est pas un entier.\n");
				erreurCompilation = 1;
			} 
			else if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : E -> E1 - E2 : E2 n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-1]->valeur)->type != ENTREE_TYPECTE_ENTIER)
			{
				printf("Erreur : Yacc : E -> E1 - E2 : E2 n'est pas un entier.\n");
				erreurCompilation = 1;
			}
			else
			{				
				//générer une varaible temporaire pour E
				bufferItoA = calloc (16, sizeof(char));
				sprintf(bufferItoA,"_SysTemp%d",nbSysTemp);
				ajoutEntreeHashTable(nouvelleEntreeCteInt(bufferItoA, 0));
				nbSysTemp++;
				printf("\t%s var temp\n",bufferItoA);
				
				charTemp1 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->nom;
				suppressionTetePileStructure();
				printf("\trécupération de %s dans la pileStructure\n",charTemp1);
				
				if(!existeMotClefHashTableHorsVide(charTemp1))
				{
					printf("Erreur : Yacc : E -> E1 - E2 : E2 : identifiant non declare (%s).\n",charTemp1);
					erreurCompilation = 1;
				}
				else
				{
					$$ = ajoutTableGencode("soustraction",bufferItoA,"",charTemp1);
					printf("\tajout : %s %s, %s, %s\n",tableGencode[$$]->commande,tableGencode[$$]->adresse1,tableGencode[$$]->adresse2,tableGencode[$$]->adresse3);
					
					//on veut ajouter à la pile E (E -> E1 op2 E2). Mais E1 est au sommet de la pile et on en a besoin lors de la réduction.
					//on supprime donc E1 de la pile, on ajoute E, on ajoute à nouveau E1. Ainsi on conserve l'ordre
					intTemp2 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->type;
					charTemp2 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->nom;
					suppressionTetePileStructure();
					ajoutPileStructureID(bufferItoA, ENTREE_TYPECTE_ENTIER);
					printf("\tajout pile %s\n",bufferItoA);	
					ajoutPileStructureID(charTemp2, intTemp2);
					printf("\tajout pile %s\n",charTemp2);	
				}
			}
		}
	| POW E		
		{
			if(pileStructure[nbPileStructure-2] == NULL || pileStructure[nbPileStructure-2]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : E -> E1 ^ E2 : E1 n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-2]->valeur)->type != ENTREE_TYPECTE_ENTIER)
			{
				printf("Erreur : Yacc : E -> E1 ^ E2 : E1 n'est pas un entier.\n");
				erreurCompilation = 1;
			} 
			else if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : E -> E1 ^ E2 : E2 n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-1]->valeur)->type != ENTREE_TYPECTE_ENTIER)
			{
				printf("Erreur : Yacc : E -> E1 ^ E2 : E2 n'est pas un entier.\n");
				erreurCompilation = 1;
			}
			else
			{				
				//générer une varaible temporaire pour E
				bufferItoA = calloc (16, sizeof(char));
				sprintf(bufferItoA,"_SysTemp%d",nbSysTemp);
				ajoutEntreeHashTable(nouvelleEntreeCteInt(bufferItoA, 0));
				nbSysTemp++;
				printf("\t%s var temp\n",bufferItoA);
				
				charTemp1 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->nom;
				suppressionTetePileStructure();
				printf("\trécupération de %s dans la pileStructure\n",charTemp1);
				
				if(!existeMotClefHashTableHorsVide(charTemp1))
				{
					printf("Erreur : Yacc : E -> E1 ^ E2 : E2 : identifiant non declare (%s).\n",charTemp1);
					erreurCompilation = 1;
				}
				else
				{
					$$ = ajoutTableGencode("puissance",bufferItoA,"",charTemp1);
					printf("\tajout : %s %s, %s, %s\n",tableGencode[$$]->commande,tableGencode[$$]->adresse1,tableGencode[$$]->adresse2,tableGencode[$$]->adresse3);
					
					//on veut ajouter à la pile E (E -> E1 op2 E2). Mais E1 est au sommet de la pile et on en a besoin lors de la réduction.
					//on supprime donc E1 de la pile, on ajoute E, on ajoute à nouveau E1. Ainsi on conserve l'ordre
					intTemp2 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->type;
					charTemp2 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->nom;
					suppressionTetePileStructure();
					ajoutPileStructureID(bufferItoA, ENTREE_TYPECTE_ENTIER);
					printf("\tajout pile %s\n",bufferItoA);	
					ajoutPileStructureID(charTemp2, intTemp2);
					printf("\tajout pile %s\n",charTemp2);	
				}
			}
		}
	| OR E		
		{
			if(pileStructure[nbPileStructure-2] == NULL || pileStructure[nbPileStructure-2]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : E -> E1 OR E2 : E1 n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-2]->valeur)->type != ENTREE_TYPECTE_BOOL)
			{
				printf("Erreur : Yacc : E -> E1 OR E2 : E1 n'est pas un booleen.\n");
				erreurCompilation = 1;
			} 
			else if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : E -> E1 OR E2 : E2 n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-1]->valeur)->type != ENTREE_TYPECTE_BOOL)
			{
				printf("Erreur : Yacc : E -> E1 OR E2 : E2 n'est pas un entier.\n");
				erreurCompilation = 1;
			}
			else
			{				
				//générer une varaible temporaire pour E
				bufferItoA = calloc (16, sizeof(char));
				sprintf(bufferItoA,"_SysTemp%d",nbSysTemp);
				ajoutEntreeHashTable(nouvelleEntreeCteBool(bufferItoA, FAUX));
				nbSysTemp++;
				printf("\t%s var temp\n",bufferItoA);
			
				charTemp1 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->nom;
				suppressionTetePileStructure();
				printf("\trécupération de %s dans la pileStructure\n",charTemp1);
				
				if(!existeMotClefHashTableHorsVide(charTemp1))
				{
					printf("Erreur : Yacc : E -> E1 OR E2 : E2 : identifiant non declare (%s).\n",charTemp1);
					erreurCompilation = 1;
				}
				else
				{
					$$ = ajoutTableGencode("logiqueOr",bufferItoA,"",charTemp1);
					printf("\tajout (%d) : %s %s, %s, %s\n",$$,tableGencode[$$]->commande,tableGencode[$$]->adresse1,tableGencode[$$]->adresse2,tableGencode[$$]->adresse3);
					
					//on veut ajouter à la pile E (E -> E1 op2 E2). Mais E1 est au sommet de la pile et on en a besoin lors de la réduction.
					//on supprime donc E1 de la pile, on ajoute E, on ajoute à nouveau E1. Ainsi on conserve l'ordre
					intTemp2 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->type;
					charTemp2 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->nom;
					suppressionTetePileStructure();
					ajoutPileStructureID(bufferItoA, ENTREE_TYPECTE_BOOL);
					printf("\tajout pile %s\n",bufferItoA);	
					ajoutPileStructureID(charTemp2, intTemp2);
					printf("\tajout pile %s\n",charTemp2);	
				}
			}
		} 
	| AND E		
		{
			if(pileStructure[nbPileStructure-2] == NULL || pileStructure[nbPileStructure-2]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : E -> E1 AND E2 : E1 n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-2]->valeur)->type != ENTREE_TYPECTE_BOOL)
			{
				printf("Erreur : Yacc : E -> E1 AND E2 : E1 n'est pas un booleen.\n");
				erreurCompilation = 1;
			} 
			else if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : E -> E1 AND E2 : E2 n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-1]->valeur)->type != ENTREE_TYPECTE_BOOL)
			{
				printf("Erreur : Yacc : E -> E1 AND E2 : E2 n'est pas un entier.\n");
				erreurCompilation = 1;
			}
			else
			{				
				//générer une varaible temporaire pour E
				bufferItoA = calloc (16, sizeof(char));
				sprintf(bufferItoA,"_SysTemp%d",nbSysTemp);
				ajoutEntreeHashTable(nouvelleEntreeCteBool(bufferItoA, FAUX));
				nbSysTemp++;
				printf("\t%s var temp\n",bufferItoA);
			
				charTemp1 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->nom;
				suppressionTetePileStructure();
				printf("\trécupération de %s dans la pileStructure\n",charTemp1);
				
				if(!existeMotClefHashTableHorsVide(charTemp1))
				{
					printf("Erreur : Yacc : E -> E1 AND E2 : E2 : identifiant non declare (%s).\n",charTemp1);
					erreurCompilation = 1;
				}
				else
				{
					$$ = ajoutTableGencode("logiqueAnd",bufferItoA,"",charTemp1);
					printf("\tajout (%d) : %s %s, %s, %s\n",$$,tableGencode[$$]->commande,tableGencode[$$]->adresse1,tableGencode[$$]->adresse2,tableGencode[$$]->adresse3);
					
					//on veut ajouter à la pile E (E -> E1 op2 E2). Mais E1 est au sommet de la pile et on en a besoin lors de la réduction.
					//on supprime donc E1 de la pile, on ajoute E, on ajoute à nouveau E1. Ainsi on conserve l'ordre
					intTemp2 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->type;
					charTemp2 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->nom;
					suppressionTetePileStructure();
					ajoutPileStructureID(bufferItoA, ENTREE_TYPECTE_BOOL);
					printf("\tajout pile %s\n",bufferItoA);	
					ajoutPileStructureID(charTemp2, intTemp2);
					printf("\tajout pile %s\n",charTemp2);	
				}
			}
		}
	| XOR E		
		{		
			if(pileStructure[nbPileStructure-2] == NULL || pileStructure[nbPileStructure-2]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : E -> E1 XOR E2 : E1 n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-2]->valeur)->type != ENTREE_TYPECTE_BOOL)
			{
				printf("Erreur : Yacc : E -> E1 XOR E2 : E1 n'est pas un booleen.\n");
				erreurCompilation = 1;
			} 
			else if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : E -> E1 XOR E2 : E2 n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-1]->valeur)->type != ENTREE_TYPECTE_BOOL)
			{
				printf("Erreur : Yacc : E -> E1 XOR E2 : E2 n'est pas un entier.\n");
				erreurCompilation = 1;
			}
			else
			{				
				//générer une varaible temporaire pour B
				bufferItoA = calloc (16, sizeof(char));
				sprintf(bufferItoA,"_SysTemp%d",nbSysTemp);
				ajoutEntreeHashTable(nouvelleEntreeCteBool(bufferItoA, FAUX));
				nbSysTemp++;
				printf("\t%s var temp\n",bufferItoA);
			
				charTemp1 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->nom;
				suppressionTetePileStructure();
				printf("\trécupération de %s dans la pileStructure\n",charTemp1);
				
				if(!existeMotClefHashTableHorsVide(charTemp1))
				{
					printf("Erreur : Yacc : E -> E1 XOR E2 : E2 : identifiant non declare (%s).\n",charTemp1);
					erreurCompilation = 1;
				}
				else
				{
					$$ = ajoutTableGencode("logiqueXor",bufferItoA,"",charTemp1);
					printf("\tajout (%d) : %s %s, %s, %s\n",$$,tableGencode[$$]->commande,tableGencode[$$]->adresse1,tableGencode[$$]->adresse2,tableGencode[$$]->adresse3);
					
					//on veut ajouter à la pile E (E -> E1 op2 E2). Mais E1 est au sommet de la pile et on en a besoin lors de la réduction.
					//on supprime donc E1 de la pile, on ajoute E, on ajoute à nouveau E1. Ainsi on conserve l'ordre
					intTemp2 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->type;
					charTemp2 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->nom;
					suppressionTetePileStructure();
					ajoutPileStructureID(bufferItoA, ENTREE_TYPECTE_BOOL);
					printf("\tajout pile %s\n",bufferItoA);	
					ajoutPileStructureID(charTemp2, intTemp2);
					printf("\tajout pile %s\n",charTemp2);	
				}
			}
		}
	| EGAL E		
		{
			if(pileStructure[nbPileStructure-2] == NULL || pileStructure[nbPileStructure-2]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : E -> E1 EGAL E2 : E1 n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-2]->valeur)->type != ENTREE_TYPECTE_ENTIER)
			{
				printf("Erreur : Yacc : E -> E1 EGAL E2 : E1 n'est pas un entier.\n");
				erreurCompilation = 1;
			} 
			else if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : E -> E1 EGAL E2 : E2 n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-1]->valeur)->type != ENTREE_TYPECTE_ENTIER)
			{
				printf("Erreur : Yacc : E -> E1 EGAL E2 : E2 n'est pas un entier.\n");
				erreurCompilation = 1;
			}
			else
			{				
				//générer une varaible temporaire pour B
				bufferItoA = calloc (16, sizeof(char));
				sprintf(bufferItoA,"_SysTemp%d",nbSysTemp);
				ajoutEntreeHashTable(nouvelleEntreeCteBool(bufferItoA, FAUX));
				nbSysTemp++;
				printf("\t%s var temp\n",bufferItoA);
			
				charTemp1 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->nom;
				suppressionTetePileStructure();
				printf("\trécupération de %s dans la pileStructure\n",charTemp1);
				
				if(!existeMotClefHashTableHorsVide(charTemp1))
				{
					printf("Erreur : Yacc : E -> E1 EGAL E2 : E2 : identifiant non declare (%s).\n",charTemp1);
					erreurCompilation = 1;
				}
				else
				{
					$$ = ajoutTableGencode("logiqueEgal",bufferItoA,"",charTemp1);
					printf("\tajout : %s %s, %s, %s\n",tableGencode[$$]->commande,tableGencode[$$]->adresse1,tableGencode[$$]->adresse2,tableGencode[$$]->adresse3);
					
					//on veut ajouter à la pile E (E -> E1 op2 E2). Mais E1 est au sommet de la pile et on en a besoin lors de la réduction.
					//on supprime donc E1 de la pile, on ajoute E, on ajoute à nouveau E1. Ainsi on conserve l'ordre
					intTemp2 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->type;
					charTemp2 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->nom;
					suppressionTetePileStructure();
					ajoutPileStructureID(bufferItoA, ENTREE_TYPECTE_BOOL);
					printf("\tajout pile %s\n",bufferItoA);	
					ajoutPileStructureID(charTemp2, intTemp2);
					printf("\tajout pile %s\n",charTemp2);	
				}
			}
		}
	| DIFFERENT E		
		{
			if(pileStructure[nbPileStructure-2] == NULL || pileStructure[nbPileStructure-2]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : E -> E1 DIFFERENT E2 : E1 n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-2]->valeur)->type != ENTREE_TYPECTE_ENTIER)
			{
				printf("Erreur : Yacc : E -> E1 DIFFERENT E2 : E1 n'est pas un entier.\n");
				erreurCompilation = 1;
			} 
			else if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : E -> E1 DIFFERENT E2 : E2 n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-1]->valeur)->type != ENTREE_TYPECTE_ENTIER)
			{
				printf("Erreur : Yacc : E -> E1 DIFFERENT E2 : E2 n'est pas un entier.\n");
				erreurCompilation = 1;
			}
			else
			{				
				//générer une varaible temporaire pour B
				bufferItoA = calloc (16, sizeof(char));
				sprintf(bufferItoA,"_SysTemp%d",nbSysTemp);
				ajoutEntreeHashTable(nouvelleEntreeCteBool(bufferItoA, FAUX));
				nbSysTemp++;
				printf("\t%s var temp\n",bufferItoA);
			
				charTemp1 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->nom;
				suppressionTetePileStructure();
				printf("\trécupération de %s dans la pileStructure\n",charTemp1);
				
				if(!existeMotClefHashTableHorsVide(charTemp1))
				{
					printf("Erreur : Yacc : E -> E1 DIFFERENT E2 : E2 : identifiant non declare (%s).\n",charTemp1);
					erreurCompilation = 1;
				}
				else
				{
					$$ = ajoutTableGencode("logiqueDifferent",bufferItoA,"",charTemp1);
					printf("\tajout : %s %s, %s, %s\n",tableGencode[$$]->commande,tableGencode[$$]->adresse1,tableGencode[$$]->adresse2,tableGencode[$$]->adresse3);
					
					//on veut ajouter à la pile E (E -> E1 op2 E2). Mais E1 est au sommet de la pile et on en a besoin lors de la réduction.
					//on supprime donc E1 de la pile, on ajoute E, on ajoute à nouveau E1. Ainsi on conserve l'ordre
					intTemp2 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->type;
					charTemp2 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->nom;
					suppressionTetePileStructure();
					ajoutPileStructureID(bufferItoA, ENTREE_TYPECTE_BOOL);
					printf("\tajout pile %s\n",bufferItoA);	
					ajoutPileStructureID(charTemp2, intTemp2);
					printf("\tajout pile %s\n",charTemp2);	
				}
			}
		}
	| PPETITS E		
		{
			if(pileStructure[nbPileStructure-2] == NULL || pileStructure[nbPileStructure-2]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : E -> E1 PPETITS E2 : E1 n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-2]->valeur)->type != ENTREE_TYPECTE_ENTIER)
			{
				printf("Erreur : Yacc : E -> E1 PPETITS E2 : E1 n'est pas un entier.\n");
				erreurCompilation = 1;
			} 
			else if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : E -> E1 PPETITS E2 : E2 n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-1]->valeur)->type != ENTREE_TYPECTE_ENTIER)
			{
				printf("Erreur : Yacc : E -> E1 PPETITS E2 : E2 n'est pas un entier.\n");
				erreurCompilation = 1;
			}
			else
			{				
				//générer une varaible temporaire pour B
				bufferItoA = calloc (16, sizeof(char));
				sprintf(bufferItoA,"_SysTemp%d",nbSysTemp);
				ajoutEntreeHashTable(nouvelleEntreeCteBool(bufferItoA, FAUX));
				nbSysTemp++;
				printf("\t%s var temp\n",bufferItoA);
			
				charTemp1 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->nom;
				suppressionTetePileStructure();
				printf("\trécupération de %s dans la pileStructure\n",charTemp1);
				
				if(!existeMotClefHashTableHorsVide(charTemp1))
				{
					printf("Erreur : Yacc : E -> E1 PPETITS E2 : E2 : identifiant non declare (%s).\n",charTemp1);
					erreurCompilation = 1;
				}
				else
				{
					$$ = ajoutTableGencode("logiquePpetits",bufferItoA,"",charTemp1);
					printf("\tajout : %s %s, %s, %s\n",tableGencode[$$]->commande,tableGencode[$$]->adresse1,tableGencode[$$]->adresse2,tableGencode[$$]->adresse3);
					
					//on veut ajouter à la pile E (E -> E1 op2 E2). Mais E1 est au sommet de la pile et on en a besoin lors de la réduction.
					//on supprime donc E1 de la pile, on ajoute E, on ajoute à nouveau E1. Ainsi on conserve l'ordre
					intTemp2 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->type;
					charTemp2 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->nom;
					suppressionTetePileStructure();
					ajoutPileStructureID(bufferItoA, ENTREE_TYPECTE_BOOL);
					printf("\tajout pile %s\n",bufferItoA);	
					ajoutPileStructureID(charTemp2, intTemp2);
					printf("\tajout pile %s\n",charTemp2);	
				}
			}
		}
	| PPETIT E		
		{
			if(pileStructure[nbPileStructure-2] == NULL || pileStructure[nbPileStructure-2]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : E -> E1 PPETIT E2 : E1 n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-2]->valeur)->type != ENTREE_TYPECTE_ENTIER)
			{
				printf("Erreur : Yacc : E -> E1 PPETIT E2 : E1 n'est pas un entier.\n");
				erreurCompilation = 1;
			} 
			else if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : E -> E1 PPETIT E2 : E2 n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-1]->valeur)->type != ENTREE_TYPECTE_ENTIER)
			{
				printf("Erreur : Yacc : E -> E1 PPETIT E2 : E2 n'est pas un entier.\n");
				erreurCompilation = 1;
			}
			else
			{				
				//générer une varaible temporaire pour B
				bufferItoA = calloc (16, sizeof(char));
				sprintf(bufferItoA,"_SysTemp%d",nbSysTemp);
				ajoutEntreeHashTable(nouvelleEntreeCteBool(bufferItoA, FAUX));
				nbSysTemp++;
				printf("\t%s var temp\n",bufferItoA);
			
				charTemp1 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->nom;
				suppressionTetePileStructure();
				printf("\trécupération de %s dans la pileStructure\n",charTemp1);
				
				if(!existeMotClefHashTableHorsVide(charTemp1))
				{
					printf("Erreur : Yacc : E -> E1 PPETIT E2 : E2 : identifiant non declare (%s).\n",charTemp1);
					erreurCompilation = 1;
				}
				else
				{
					$$ = ajoutTableGencode("logiquePpetit",bufferItoA,"",charTemp1);
					printf("\tajout : %s %s, %s, %s\n",tableGencode[$$]->commande,tableGencode[$$]->adresse1,tableGencode[$$]->adresse2,tableGencode[$$]->adresse3);
					
					//on veut ajouter à la pile E (E -> E1 op2 E2). Mais E1 est au sommet de la pile et on en a besoin lors de la réduction.
					//on supprime donc E1 de la pile, on ajoute E, on ajoute à nouveau E1. Ainsi on conserve l'ordre
					intTemp2 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->type;
					charTemp2 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->nom;
					suppressionTetePileStructure();
					ajoutPileStructureID(bufferItoA, ENTREE_TYPECTE_BOOL);
					printf("\tajout pile %s\n",bufferItoA);	
					ajoutPileStructureID(charTemp2, intTemp2);
					printf("\tajout pile %s\n",charTemp2);	
				}
			}
		}
	| PGRAND E		
		{
			if(pileStructure[nbPileStructure-2] == NULL || pileStructure[nbPileStructure-2]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : E -> E1 PGRAND E2 : E1 n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-2]->valeur)->type != ENTREE_TYPECTE_ENTIER)
			{
				printf("Erreur : Yacc : E -> E1 PGRAND E2 : E1 n'est pas un entier.\n");
				erreurCompilation = 1;
			} 
			else if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : E -> E1 PGRAND E2 : E2 n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-1]->valeur)->type != ENTREE_TYPECTE_ENTIER)
			{
				printf("Erreur : Yacc : E -> E1 PGRAND E2 : E2 n'est pas un entier.\n");
				erreurCompilation = 1;
			}
			else
			{				
				//générer une varaible temporaire pour E
				bufferItoA = calloc (16, sizeof(char));
				sprintf(bufferItoA,"_SysTemp%d",nbSysTemp);
				ajoutEntreeHashTable(nouvelleEntreeCteBool(bufferItoA, FAUX));
				nbSysTemp++;
				printf("\t%s var temp\n",bufferItoA);
			
				charTemp1 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->nom;
				suppressionTetePileStructure();
				printf("\trécupération de %s dans la pileStructure\n",charTemp1);
				
				if(!existeMotClefHashTableHorsVide(charTemp1))
				{
					printf("Erreur : Yacc : E -> E1 PGRAND E2 : E2 : identifiant non declare (%s).\n",charTemp1);
					erreurCompilation = 1;
				}
				else
				{
					$$ = ajoutTableGencode("logiquePgrand",bufferItoA,"",charTemp1);
					printf("\tajout : %s %s, %s, %s\n",tableGencode[$$]->commande,tableGencode[$$]->adresse1,tableGencode[$$]->adresse2,tableGencode[$$]->adresse3);
					
					//on veut ajouter à la pile E (E -> E1 op2 E2). Mais E1 est au sommet de la pile et on en a besoin lors de la réduction.
					//on supprime donc E1 de la pile, on ajoute E, on ajoute à nouveau E1. Ainsi on conserve l'ordre
					intTemp2 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->type;
					charTemp2 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->nom;
					suppressionTetePileStructure();
					ajoutPileStructureID(bufferItoA, ENTREE_TYPECTE_BOOL);
					printf("\tajout pile %s\n",bufferItoA);	
					ajoutPileStructureID(charTemp2, intTemp2);
					printf("\tajout pile %s\n",charTemp2);	
				}
			}
		}
	| PGRANDS E		
		{
			if(pileStructure[nbPileStructure-2] == NULL || pileStructure[nbPileStructure-2]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : E -> E1 PGRANDS E2 : E1 n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-2]->valeur)->type != ENTREE_TYPECTE_ENTIER)
			{
				printf("Erreur : Yacc : E -> E1 PGRANDS E2 : E1 n'est pas un entier.\n");
				erreurCompilation = 1;
			} 
			else if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : E -> E1 PGRANDS E2 : E2 n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-1]->valeur)->type != ENTREE_TYPECTE_ENTIER)
			{
				printf("Erreur : Yacc : E -> E1 PGRANDS E2 : E2 n'est pas un entier.\n");
				erreurCompilation = 1;
			}
			else
			{				
				//générer une varaible temporaire pour B
				bufferItoA = calloc (16, sizeof(char));
				sprintf(bufferItoA,"_SysTemp%d",nbSysTemp);
				ajoutEntreeHashTable(nouvelleEntreeCteBool(bufferItoA, FAUX));
				nbSysTemp++;
				printf("\t%s var temp\n",bufferItoA);
			
				charTemp1 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->nom;
				suppressionTetePileStructure();
				printf("\trécupération de %s dans la pileStructure\n",charTemp1);
				
				if(!existeMotClefHashTableHorsVide(charTemp1))
				{
					printf("Erreur : Yacc : E -> E1 PGRANDS E2 : E2 : identifiant non declare (%s).\n",charTemp1);
					erreurCompilation = 1;
				}
				else
				{
					$$ = ajoutTableGencode("logiquePgrands",bufferItoA,"",charTemp1);
					printf("\tajout : %s %s, %s, %s\n",tableGencode[$$]->commande,tableGencode[$$]->adresse1,tableGencode[$$]->adresse2,tableGencode[$$]->adresse3);
					
					//on veut ajouter à la pile E (E -> E1 op2 E2). Mais E1 est au sommet de la pile et on en a besoin lors de la réduction.
					//on supprime donc E1 de la pile, on ajoute E, on ajoute à nouveau E1. Ainsi on conserve l'ordre
					intTemp2 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->type;
					charTemp2 = ((structureID)pileStructure[nbPileStructure-1]->valeur)->nom;
					suppressionTetePileStructure();
					ajoutPileStructureID(bufferItoA, ENTREE_TYPECTE_BOOL);
					printf("\tajout pile %s\n",bufferItoA);	
					ajoutPileStructureID(charTemp2, intTemp2);
					printf("\tajout pile %s\n",charTemp2);	
				}
			}
		}
	;

appelfonction : IDENTIFIANT PGAUCHE 
		{
			if(!existeMotClefHashTableHorsVide(tableValueText[$1]))
			{
				printf("Erreur : Yacc : appelfonction : IDENTIFIANT PGAUCHE paramlist PDROITE : identifiant non declare (%s).\n",tableValueText[$1]);
				erreurCompilation = 1;
			}
			else if(consulteHashTable(tableValueText[$1]).typeEntree == ENTREE_TYPEENTREE_FCT)
			{
				temporaire = consulteHashTable(tableValueText[$1]);
				ajoutPileStructureFONCTION(temporaire.nom, temporaire.nbArg, temporaire.typeArg, temporaire.typeRetour);
				
				intTemp1 = ajoutTableGencode("sauveRA","","","");
				printf("\tajout (%d) : %s %s, %s, %s\n",intTemp1, tableGencode[intTemp1]->commande,tableGencode[intTemp1]->adresse1,tableGencode[intTemp1]->adresse2,tableGencode[intTemp1]->adresse3);
			}
			else
			{
				printf("Erreur : Yacc : appelfonction : IDENTIFIANT PGAUCHE paramlist PDROITE : identifiant n'est pas une fonction (%s).\n",tableValueText[$1]);
				erreurCompilation = 1;
			}			
			
			suppressionTableValueText($1);
		}
		paramlist PDROITE
		{
			intTemp1 = 1;
			
			while(intTemp1 <= 4 && (nbPileStructure-intTemp1)>=0 && pileStructure[nbPileStructure-intTemp1] != NULL && pileStructure[nbPileStructure-intTemp1]->type != PILESTRUCTURE_TYPE_FONCTION)
			{
				intTemp1++;
			}
		
			if(pileStructure[nbPileStructure-intTemp1] == NULL || pileStructure[nbPileStructure-intTemp1]->type != PILESTRUCTURE_TYPE_FONCTION)
			{
				printf("Erreur : Yacc : appelfonction : IDENTIFIANT PGAUCHE paramlist PDROITE : la tete de pile n'est pas une focntion.\n");
				erreurCompilation = 1;
			}
			else
			{
				intTemp3 = ((structureFONCTION)(pileStructure[nbPileStructure-intTemp1]->valeur))->nbArg;
				intEtoileTemp1 = ((structureFONCTION)(pileStructure[nbPileStructure-intTemp1]->valeur))->typeArg;
				charTemp1 = ((structureFONCTION)(pileStructure[nbPileStructure-intTemp1]->valeur))->nom;
				
				for(intTemp2=intTemp3-1; intTemp2>=0; intTemp2--)
				{
					if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_ID)
					{
						printf("Erreur : Yacc : appelfonction : IDENTIFIANT PGAUCHE paramlist PDROITE : un parametre n'est pas un identifiant.\n");
						erreurCompilation = 1;
					}
					else if(((structureID)pileStructure[nbPileStructure-1]->valeur)->type != intEtoileTemp1[intTemp2])
					{
						printf("Erreur : Yacc : appelfonction : IDENTIFIANT PGAUCHE paramlist PDROITE : un argument n'est pas du bon type.\n");
						erreurCompilation = 1;
					} 
					else
					{
						bufferItoA = calloc (16, sizeof(char));
						sprintf(bufferItoA,"$a%d",intTemp2);					
						intTemp1 = ajoutTableGencode("chargerDansParametre",((structureID)pileStructure[nbPileStructure-1]->valeur)->nom,bufferItoA,"");
						printf("\tajout (%d) : %s %s, %s, %s\n",intTemp1, tableGencode[intTemp1]->commande,tableGencode[intTemp1]->adresse1,tableGencode[intTemp1]->adresse2,tableGencode[intTemp1]->adresse3);
						
						suppressionTetePileStructure();
					}
				}
				
				if(intTemp2 > -1)
				{
					printf("Erreur : Yacc : appelfonction : IDENTIFIANT PGAUCHE paramlist PDROITE : il manque des arguments.\n");
					erreurCompilation = 1;
				}
				else if(intTemp2 < -1)
				{
					printf("Erreur : Yacc : appelfonction : IDENTIFIANT PGAUCHE paramlist PDROITE : il y a trop d'arguments.\n");
					erreurCompilation = 1;
				}
				else
				{
					intTemp1 = ajoutTableGencode("appelFonction",charTemp1,"","");
					printf("\tajout (%d) : %s %s, %s, %s\n",intTemp1, tableGencode[intTemp1]->commande,tableGencode[intTemp1]->adresse1,tableGencode[intTemp1]->adresse2,tableGencode[intTemp1]->adresse3);
					
					intTemp1 = ajoutTableGencode("chargeRA","","","");
					printf("\tajout (%d) : %s %s, %s, %s\n",intTemp1, tableGencode[intTemp1]->commande,tableGencode[intTemp1]->adresse1,tableGencode[intTemp1]->adresse2,tableGencode[intTemp1]->adresse3);
				}
			}
		}
	| IDENTIFIANT PGAUCHE PDROITE
		{
			if(!existeMotClefHashTableHorsVide(tableValueText[$1]))
			{
				printf("Erreur : Yacc : appelfonction : IDENTIFIANT PGAUCHE PDROITE : identifiant non declare (%s).\n",tableValueText[$1]);
				erreurCompilation = 1;
			}
			else if(consulteHashTable(tableValueText[$1]).typeEntree == ENTREE_TYPEENTREE_FCT)
			{
				temporaire = consulteHashTable(tableValueText[$1]);
				ajoutPileStructureFONCTION(temporaire.nom, temporaire.nbArg, temporaire.typeArg, temporaire.typeRetour);
				
				if(temporaire.nbArg != 0)
				{
					printf("Erreur : Yacc : appelfonction : IDENTIFIANT PGAUCHE PDROITE : la fonction %s attend des arguments.\n",tableValueText[$1]);
					erreurCompilation = 1;
				}
				else
				{
					intTemp1 = ajoutTableGencode("sauveRA","","","");
					printf("\tajout (%d) : %s %s, %s, %s\n",intTemp1, tableGencode[intTemp1]->commande,tableGencode[intTemp1]->adresse1,tableGencode[intTemp1]->adresse2,tableGencode[intTemp1]->adresse3);
					
					intTemp1 = ajoutTableGencode("appelFonction",temporaire.nom,"","");
					printf("\tajout (%d) : %s %s, %s, %s\n",intTemp1, tableGencode[intTemp1]->commande,tableGencode[intTemp1]->adresse1,tableGencode[intTemp1]->adresse2,tableGencode[intTemp1]->adresse3);
					
					intTemp1 = ajoutTableGencode("chargeRA","","","");
					printf("\tajout (%d) : %s %s, %s, %s\n",intTemp1, tableGencode[intTemp1]->commande,tableGencode[intTemp1]->adresse1,tableGencode[intTemp1]->adresse2,tableGencode[intTemp1]->adresse3);	
				}				
			}
			else
			{
				printf("Erreur : Yacc : appelfonction : IDENTIFIANT PGAUCHE PDROITE : identifiant n'est pas une fonction (%s).\n",tableValueText[$1]);
				erreurCompilation = 1;
			}			
			
			suppressionTableValueText($1);
		}
	;	

paramlist : param VIRGULE paramlist
	| param
	;

param : E
	;
	
ifthen : IF E
		{
			if(pileStructure[nbPileStructure-1] == NULL || pileStructure[nbPileStructure-1]->type != PILESTRUCTURE_TYPE_ID)
			{
				printf("Erreur : Yacc : IF E THEN instr [ELSE instr] : E n'est pas un identifiant.\n");
				erreurCompilation = 1;
			}
			else if(((structureID)pileStructure[nbPileStructure-1]->valeur)->type == ENTREE_TYPECTE_BOOL)
			{				
				intTemp1 = nbLabelPourGenMips;
				nbLabelPourGenMips += 2;
				
				bufferItoA = calloc (16, sizeof(char));
				sprintf(bufferItoA,"_SysLabelGenMips%d",intTemp1);
				
				ajoutTableGencode("if",((structureID)pileStructure[nbPileStructure-1]->valeur)->nom,bufferItoA,"");
				suppressionTetePileStructure();
				
				ajoutPileStructureIFTHENELSE(intTemp1,intTemp1+1);
			}
			else
			{
				printf("Erreur : Yacc : IF E THEN instr [ELSE instr] : E n'est pas un booleen.\n");
				erreurCompilation = 1;
			}
		}
		THEN instr
	;
	
%%

int yyerror(char * s)
{
	printf("\nErreur : %s\n\n", s);
	exit(-1);
}

int main (int argc, char ** argv)
{
	nbSysTemp = 0;

	if(argc != 2)
	{
		printf("\nUsage : %s <nom fichier en entrée>\n\n",argv[0]);
		exit(-1);
	}	
	
	if ((yyin = fopen(argv[1], "r")) == NULL)
	{                  
		printf("\nErreur : impossible d'ouvrir le fichier %s\n\n", argv[1]);
		exit(-1);
	}
	
	initVariableADeclarer();
	initTableGencode();
	initHashTable();
	initPiles();
	initPourGestionPile();
	initPileStructure();
	initGenMips();
	erreurCompilation = 0;
	
	printf("Debut analyse\n");
	yyparse();
	if(!hashTableVide())
	{
		sortieBloc();
	}
	printf("Fin analyse\n\n");
	
	//afficheTableGencode();

	if(erreurCompilation)
	{
		printf("Erreur : Yacc : il y a eu des erreurs à la compilation.\n");
		exit(-1);
	}
		
	printf("Debut génération mips\n");
	mipsGeneration(yyout);
	printf("Fin génération mips\n");
	
	fclose(yyin);	
	fclose(yyout);
	
	return 0;
}
